home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 050 / madtrb34.arc / KBM.ASM < prev    next >
Assembly Source File  |  1986-02-06  |  10KB  |  242 lines

  1. ; This program intecepts keyboard data and creates a bit pattern determined
  2. ; according to whether or not certain keys are currently being pressed.
  3. ;
  4. ; The bit pattern is stored in the "inter-application communication area"
  5. ; at 0000:04f0.  It is interpreted as:
  6. ;
  7. ; 7 6 5 4 3 2 1 0   (bit number)
  8. ; C m P H l d r u   (bit name)
  9. ; | | | | | | | |
  10. ; | | | | | | | +- bit 0 (01h) - set = 1 while [up arrow] is pressed
  11. ; | | | | | | +--- bit 1 (02h) - set = 1 while [right arrow] is pressed
  12. ; | | | | | +----- bit 2 (04h) - set = 1 while [down arrow] is pressed
  13. ; | | | | +------- bit 3 (08h) - set = 1 while [left arrow] is pressed
  14. ; | | | |
  15. ; | | | +--------- bit 4 (10h) - set = 1 while [Home] is pressed
  16. ; | | +----------- bit 5 (20h) - set = 1 while [PgUp] is pressed
  17. ; | +------------- bit 6 (40h) - set = 1 while grey [-] is pressed
  18. ; +--------------- bit 7 (80h) - set = 1 while [CapsLock] is pressed
  19. ;
  20. ; As soon as the key is released, the relevant bit is reset to 0.
  21. ;
  22. ; The byte at 0000:04f1 is the "pass-through/filter" mode flag.  When this
  23. ; byte is zero, all keystrokes are passed to the normal keyboard handler.
  24. ; When it's non-zero, all selected keystrokes are filtered (disabled for
  25. ; normal input).  BIOS and DOS keyboard calls will not recognize them.
  26. ;
  27. ; The Alt-NumLock keystrokes toggles between pass-through and filter modes.
  28. ;
  29. ; This program is installed and remains resident.  It is a COM-format
  30. ; file, so it must be converted with EXE2BIN.
  31. ;
  32. ; Copyright (c) Ziff-Davis Publishing Co., 1986.  All rights reserved.
  33. ;
  34. ; = equates ===============
  35.  
  36. KB_DATA_PORT     equ     60h     ; These are listed in the PC and XT
  37. KB_CTRL_PORT     equ     61h     ; Technical Reference Manuals
  38.  
  39. KB_FLAG          equ     417h    ; the BIOS shift-key status (in segment 0)
  40. ALT_STATE        equ       8     ;  Bit pattern while the [Alt] key is pressed
  41. NUMLOCK_KEY      equ      69     ;  scan-code of the [NumLock] key
  42.  
  43. INT_CTL_PORT     equ      20h    ; Interrupt controller port (8259 chip)
  44. EOI              equ      20h    ; End-Of-Interrupt code sent to 8259
  45.  
  46. RELEASE_BIT      equ      80h    ;also called the "break" bit: a key was pressed
  47.  
  48. KEY_BITS         equ    04f0h    ;the address of the key bits flags (segment 0)
  49. MODE_FLAG        equ    04f1h    ;when 0, all keys are passed to normal kbint
  50. INST_FLAG        equ    04f2h    ; set to 1234h during installation.
  51.  
  52. com_seg  segment
  53.          assume  cs:com_seg,ds:com_seg
  54.          org     100h                   ; must have for COM-file format program
  55. kbm      proc    far
  56.          jmp     set_up   ; get past data and install interrupt handler
  57.  
  58. ; ============= program data area ==========
  59.  
  60. norm_key_int     label dword       ; type DWORD so it can be used in a FAR jump
  61. nki_offset       dw    0           ; This address is stored in the SET_UP proc
  62. nki_segment      dw    0         ; It's the address of the previous kbint routine
  63.  
  64. ; ------------------------------------------------------------------------
  65. ; KBD_INT
  66. ; 1.) read the keyboard
  67. ; 2.) set/reset bits in mouse movement byte
  68. ; 3.) execute normal keyboard interrupt
  69. ;
  70. ;           scan  bit     key        suggested meaning
  71. ;           code  flag    name       (defined by user)
  72. ;           ----  ----    ---------  --------------------
  73. kbd_tbl  db   72,  1 ;    num.pad 8  go up
  74.          db   77,  2 ;    num.pad 6  go right
  75.          db   80,  4 ;    num.pad 2  go down
  76.          db   75,  8 ;    num.pad 4  go left
  77.  
  78.          db   76,  4 ;    num.pad 5  go down
  79.          db   71, 16 ;    Home       button 1
  80.          db   73, 32 ;    PgUp       button 2
  81.          db   74, 64 ;    grey minus button 3
  82.          db   58, 128;    CapsLock   "high-gear shift" for fast motion
  83. tbl_end  label byte
  84.  
  85. ; ------------------------------------------------------------------------
  86. ; KBD_INT
  87. ; This procedure intercepts the ROM-BIOS KB_INT.
  88. ; It sets and resets bits of a kbd flag as the user presses and releases keys.
  89. ; When the byte at 0000:04f1 is 0, the keystroke is passed on to the
  90. ; original keyboard handler.
  91.  
  92. kbd_int  proc    far
  93.          sti
  94.          cld
  95.          push    ax
  96.          push    si
  97.          push    ds
  98.  
  99.          in      al,KB_DATA_PORT ; read scan-code from keyboard into AL
  100.          mov     ah,al           ; save original byte in AH
  101.          and     al,7fh          ; mask off "release bit" for comparison
  102.  
  103.          mov     si,offset kbd_tbl
  104.  
  105. k_20:    cmp     si,offset tbl_end   ; at end of table?
  106.          ja      k_25                ; yes, key not found. Exit to normal kbint
  107.          cmp     al,byte ptr cs:[si] ; is this the key?
  108.          je      k_30                ;  yes, process the keystroke
  109.          inc     si                  ;  no, point past the scan mode
  110.          inc     si                  ;      point past the bit-mask
  111.          jmp     k_20                ;      and loop back to the next entry
  112. k_25:
  113. ;------- check for mode-toggle by user
  114.          cmp     ah,NUMLOCK_KEY      ; is this a press of [NumLock]
  115.          jne     k_27                ;   no, go
  116.          sub     si,si               ;   yes, look to BIOS data area
  117.          mov     ds,si
  118.          test    byte ptr ds:[KB_FLAG],ALT_STATE ; is [Alt] pressed?
  119.          jz      k_27                            ;   no, pass the key on
  120.  
  121.          xor     byte ptr ds:[MODE_FLAG],1       ;   yes, toggle the mode and
  122.          jmp     short k_exit                    ;        exit w/o processing
  123.  
  124. ;------- the keystroke is to be processed by the normal keyboard interrupt
  125. k_27:    pop     ds
  126.          pop     si
  127.          pop     ax
  128.          jmp     cs:[norm_key_int]        ; continue at normal keyboard handler
  129.  
  130. k_30:
  131. ;------- process the scan code into a bit-pattern
  132.          mov     al,cs:[si+1]      ; get bit-flag mask
  133.  
  134.          sub     si,si
  135.          mov     ds,si             ; point to segment of KEY_BITS
  136.  
  137.          test    ah,RELEASE_BIT    ; is this key being released?
  138.          jz      k_40              ; no, go
  139.  
  140. ;------- process key release
  141.          not     al                           ; flip-flop mask bits
  142.          and     byte ptr ds:[KEY_BITS],al    ; mask off released key bit
  143.          jmp     k_50
  144. k_40:
  145. ;------- process key press
  146.          or      byte ptr ds:[KEY_BITS],al    ; set the bit for pressed key
  147.  
  148. ;------- determine whether key should be passed or to normal keyboard handler
  149. k_50:
  150.          cmp     byte ptr ds:[MODE_FLAG],0    ;should key be processed further?
  151.          je      k_27                         ;  yes, continue at kb int
  152.  
  153. ;------ the keystroke is to be ignored by the rest of the system.
  154. ;------ wrap up this keyboard interrupt.
  155.  
  156. k_exit:  in      al,KB_CTRL_PORT  ; get current value of keyboard control lines
  157.          mov     ah,al            ;   save it
  158.          or      al,80h           ; set the "enable kbd" but
  159.          out     KB_CTRL_PORT,al  ;   and write it out the control port
  160.          xchg    ah,al            ; fetch the original control port value
  161.          out     KB_CTRL_PORT,al  ;   and write it back
  162.  
  163.          pop     ds
  164.          pop     si
  165.  
  166.          cli
  167.          mov     al,EOI           ; send End-Of-Interrupt signal
  168.          out     INT_CTL_PORT,al  ;  to the 8259 Interrupt Controller
  169.          pop     ax
  170.          iret                     ; exit to interrupted program
  171. kbd_int  endp
  172.  
  173. LAST_BYTE equ    offset $+1   ; This is the address passed to INT 27H
  174.                               ; Notice that the code of SET_UP
  175.                               ;   procedure is not preserved in memory
  176. ;-------------------------------------------------------------------------
  177. ;  SET_UP
  178. ; This routine is executed only once, when the program is installed.
  179.  
  180. inst_msg  db 'KBM KeyBoard Mouse Driver',0dh,0ah
  181.           db 'Copyright (c) 1986 Ziff-Davis Publishing Co.,',0dh,0ah,'$'
  182.  
  183. err_msg1  db 07,'Already installed',0dh,0ah,'$'
  184. err_msg2  db 'Wrong DOS version.',0dh,0ah,'$'
  185.  
  186. set_up    proc   near
  187.  
  188. ;-------- make sure this is DOS 2.0 or later
  189.           mov    ah,30h
  190.           int    21h
  191.           cmp    al,2
  192.           jae    su_10
  193.           mov    dx,offset err_msg2
  194.           jmp    msg_exit
  195. su_10:
  196. ;-------- see if KBM has already been installed
  197.           mov    ax,0
  198.           mov    es,ax
  199.           cmp    es:[INST_FLAG],1234h    ; Already installed?
  200.           jne    su_20                   ;  no, continue
  201.           mov    dx,offset err_msg1      ;  yes, exit with message
  202.           jmp    msg_exit
  203. su_20:    mov    word ptr es:[INST_FLAG],1234h   ; flag says KBM is installed
  204.  
  205. ;-------- save the old kbint vector and set up the new one
  206.           mov    al,9
  207.           mov    ah,35h                  ; DOS GET_VECTOR service
  208.           int    21h                     ;  for interrupt 9 [KBINT]
  209.  
  210.           mov    al,9                 ;get address of the current kbint handler
  211.           mov    ah,35h               ;DOS GET_VECTOR service
  212.           int    21h
  213.           mov    nki_segment,es       ; save old address
  214.           mov    nki_offset,bx
  215.  
  216.           mov    dx,offset kbd_int ; set INT 9 to local keyboard interceptor
  217.           mov    al,9              ; set vector for INT 9 to DS:DX
  218.           mov    ah,25h            ; DOS SET_VECTOR service
  219.           int    21h
  220.  
  221.           mov    ax,0
  222.           mov    es,ax                        ; initialize variables:
  223.           mov    byte ptr es:[MODE_FLAG],0    ;   process all keystrokes
  224.           mov    byte ptr es:[KEY_BITS],0     ;   no keys are pressed
  225.  
  226. ;-------- display message to indicate install`tion complete
  227.           mov    dx,offset inst_msg
  228.           mov    ah,9
  229.           int    21h
  230.  
  231. ;-------- exit to DOS, leaving the interrupt handler resident
  232.           mov    dx,LAST_BYTE
  233.           int    27h
  234.  
  235. msg_exit: mov    ah,9
  236.           int    21h
  237.           int    20h
  238. set_up    endp
  239. kbm       endp
  240. com_seg   ends
  241.           end    kbm
  242.